/**
 * 
 */
package io.dora.conf;

import io.dora.base.ServiceInvoker;
import io.dora.invoker.DoraInvoker;
import io.dora.lb.InvokeLoadBalance;
import io.dora.lb.RandomInvokeLoadBalance;
import io.dora.registry.ServiceSynchronizer;
import io.dora.registry.zk.ZkUtils;
import io.dora.remoting.ConsumerClient;
import io.dora.remoting.NettyConsumerClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Consumer Config Bean
 * 
 * @author zhaohongbo
 *
 */
public class ConsumerConfig<T> extends AbstractServiceConfig {

	private Logger logger = LoggerFactory.getLogger(getClass());

	/** 服务分组*/
	protected String group;

	/** 接口签名 */
	protected Class<T> interfaceClass;

	/** Spring bean Id */
	protected String interfaceName;

	/** 负载均衡算法*/
	protected InvokeLoadBalance loadBalace;
	
	public String getGroup() {
		return group;
	}
	
	public void setGroup(String group) {
		this.group = group;
	}

	public Class<T> getInterfaceClass() {
		return interfaceClass;
	}

	public void setInterfaceClass(Class<T> interfaceClass) {
		this.interfaceClass = interfaceClass;
	}

	public String getInterfaceName() {
		return interfaceName;
	}

	public void setInterfaceName(String interfaceName) {
		this.interfaceName = interfaceName;
	}
	
	public String getServiceKey() {
		return ZkUtils.separator + group + ZkUtils.separator + interfaceClass.getName();
	}

	public InvokeLoadBalance getLoadBalace() {
		return loadBalace;
	}

	public void setLoadBalace(InvokeLoadBalance loadBalace) {
		this.loadBalace = loadBalace;
	}
	
	public T refer() {
		this.initial();
		ServiceInvoker<T> seviceInvoker = new DoraInvoker<T>(interfaceClass, getServiceKey(), protocol, loadBalace.select());
		try {
			return (T) seviceInvoker.invoke();
		} catch (Throwable e) {
			logger.error("{}", e);
		}
		return null;
	}
	
	public void initial() {
		this.getRegistry().lookup(this.getServiceKey());
		this.setLoadBalace(new RandomInvokeLoadBalance(this.getRegistry().get(this.getServiceKey())));
		this.initConsumerInvokerClient();
	}
	
	/**
	 * 初始化ConsumerClient
	 */
	protected void initConsumerInvokerClient() {
		String[] hostsArr = this.getLoadBalace().getProviderHosts();
		String host = "";
		int port = 0;
		for (String hosts : hostsArr) {
			String[] hostAndPort = hosts.split(":");
			
			if (hostAndPort.length > 0) {
				host = hostAndPort[0];
			}
			
			if (hostAndPort.length > 1) {
				port = Integer.parseInt(hostAndPort[1]);
			}
			
			if (!protocol.getConsumerClientMap().containsKey(hosts)) {
				ConsumerClient consumerClient = new NettyConsumerClient(host, port, protocol);
				if (consumerClient.isSuccess()) {
					protocol.getConsumerClientMap().put(hosts, consumerClient);
				}
			}
		}
		ServiceSynchronizer.get().init(protocol.getConsumerClientMap());
	}
	
}
